Email Blast Round‑Trip
This guide shows a complete round‑trip to launch an email “blast” using ValkyrAI’s Workflow Engine.
What you get:
- Recipient selection with preference filtering
- Template fetch/injection and merge with per‑recipient data
- Async send queue to Mailtrap (dry‑run or live)
- Simple stats, retries and event logging
- A passing integration test to validate the flow
Modules used
- emailRecipientsModule: Reads
recipients
frommoduleData
and exposes them asrecipients
in the map. - preferenceFilterModule: Filters recipients by
optIn
/marketingOptIn
andacceptedTos
. - contentTemplateFetchModule: Fetches
ContentData
by id and outputstemplate
andsubject
(optional; you can also use mapInjectModule). - mapInjectModule: Injects arbitrary JSON keys into the map (useful for tests or inline templates/subjects).
- templateMergeModule: Applies a Mustache‑style merge of
{{key}}
placeholders for each recipient. OutputsmailItems
. - mailtrapSendModule: Sends
mailItems
to Mailtrap with concurrency, retry anddryRun
support. OutputssendStats
andfailures
.
Environment variables
- MAILTRAP_API_ENDPOINT: Mailtrap send endpoint (e.g. https://sandbox.api.mailtrap.io/api/send/123456)
- MAILTRAP_SECRET_KEY: Mailtrap API token
Example workflow (conceptual)
- EmailRecipientsModule
- moduleData:
{ "recipients": [{"email":"user@example.com","firstName":"Sam","optIn":true}] }
- moduleData:
- PreferenceFilterModule
- moduleData:
{ "defaultOptIn": false }
- moduleData:
- ContentTemplateFetchModule or MapInjectModule
- MapInject example:
{ "template": "Hi {{firstName}}", "subject": "Hello {{firstName}}" }
- MapInject example:
- TemplateMergeModule
- moduleData:
{ "format": "text", "defaultSubject": "Hello" }
- moduleData:
- MailtrapSendModule
- moduleData:
{ "dryRun": true, "concurrency": 4, "fromEmail": "no-reply@valkyrlabs.com" }
- moduleData:
Integration test
- See
valkyrai/src/test/java/com/valkyrlabs/workflow/EmailBlastWorkflowIT.java
. - The test composes a one‑task workflow with the modules above, runs them sequentially (engine‑lite) and asserts
sendStats
:- attempted = 1, succeeded = 1, failed = 0
Notes
- To run live against Mailtrap, set the environment variables and remove
dryRun
or set it tofalse
. - For full engine execution with Quartz scheduling, register the workflow via the Workflow API and start it per your schedule.
- Event logging uses
EventLogRepository
when available; test uses dry‑run and asserts in‑memorysendStats
to avoid DB setup.